package org.wms.minbearwcs.serivce.mission.storageProcessor.locker.Floor3Or4.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.wms.minbearwcs.dao.storage.inf.DualHeadStorageDao;
import org.wms.minbearwcs.entity.DTO.transfer.Tuple;
import org.wms.minbearwcs.entity.PO.wcs.storage.dualHeadStorage.DualHeadStorage;
import org.wms.minbearwcs.serivce.mission.storageProcessor.locker.Floor3Or4.Storage3Or4FloorLocker;

import java.util.Comparator;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class Storage3Or4FloorLockerImpl implements Storage3Or4FloorLocker {

    private final DualHeadStorageDao dualHeadStorageDao;

    @Override
    public synchronized Tuple<String> lockStorage(String storagePoint, String palletCode) {
        unLockStorage(palletCode);
        List<DualHeadStorage> dualHeadStorageList = getDualHeadStorageList(storagePoint);
        dualHeadStorageList.sort(Comparator.comparingInt(DualHeadStorage::getColumnNum));

        int storagePointIndex = -1;
        for (int i = 0; i < dualHeadStorageList.size(); i++) {
            if (storagePoint.equals(dualHeadStorageList.get(i).getQrPoint())) {
                storagePointIndex = i;
                break;
            }
        }

        if (storagePointIndex == -1) return Tuple.tuple(null,false);


        int whoIsLeft = findWhoIsLeft(dualHeadStorageList,storagePointIndex);
        if (storagePointIndex < whoIsLeft) {
            boolean noLocker = true;
            for (int i = 0; i < storagePointIndex; i++) {
                if (dualHeadStorageList.get(i).getLockPallet() != null) {
                    noLocker = false;
                    break;
                }
            }
            if (noLocker) {
                for (int i = 0; i <= storagePointIndex; i++) {
                    dualHeadStorageDao.updateLockPalletById(
                            dualHeadStorageList.get(i).getId(),
                            palletCode
                    );
                }
                return Tuple.tuple(dualHeadStorageList
                        .get(0)
                        .getQrPoint(), true);
            }
        }

        int whoIsRight = findWhoIsRight(dualHeadStorageList,storagePointIndex);
        if (storagePointIndex > whoIsRight) {
            boolean noLocker = true;
            for (int i = storagePointIndex + 1; i < dualHeadStorageList.size(); i++) {
                if (dualHeadStorageList.get(i).getLockPallet() != null) {
                    noLocker = false;
                    break;
                }
            }
            if (noLocker) {
                for (int i = storagePointIndex; i < dualHeadStorageList.size(); i++) {
                    dualHeadStorageDao.updateLockPalletById(
                            dualHeadStorageList.get(i).getId(),
                            palletCode
                    );
                }
                return Tuple.tuple(dualHeadStorageList
                        .get(dualHeadStorageList.size()-1)
                        .getQrPoint(), true);
            }
        }

        return Tuple.tuple(null,false);
    }

    @Override
    public boolean unLockStorage(String palletCode) {
        return dualHeadStorageDao.updateLockPalletNullByPalletCode(palletCode);
    }


    private List<DualHeadStorage> getDualHeadStorageList(String storagePoint) {
        String groupCode = dualHeadStorageDao.selectGroupNameByQrCode(storagePoint);
        return dualHeadStorageDao.selectByDualHeadStorageGroupCode(groupCode);
    }

    private int findWhoIsLeft(List<DualHeadStorage> dualHeadStorageList,int storagePointIndex) {
        if (dualHeadStorageList.size() <= 0 || dualHeadStorageList.get(0).getIsEntrance() == 0) {
            return -1;
        }

        int whoLeft = -1;
        for (int i = 0; i < dualHeadStorageList.size(); i++) {
            if (i>=storagePointIndex){
                return Integer.MAX_VALUE;
            }
            if (judgeCanNotPass(dualHeadStorageList.get(i))) {
                whoLeft = i;
                break;
            }
        }
        return whoLeft;
    }

    private int findWhoIsRight(List<DualHeadStorage> dualHeadStorageList,int storagePointIndex) {
        if (dualHeadStorageList.size() <= 0 ||
                dualHeadStorageList.get(dualHeadStorageList.size() - 1).getIsEntrance() == 0) {
            return Integer.MAX_VALUE;
        }

        int whoRight = Integer.MAX_VALUE;
        for (int i = dualHeadStorageList.size() - 1; i >= 0; i--) {
            if (i<=storagePointIndex){
                return -1;
            }
            if (judgeCanNotPass(dualHeadStorageList.get(i))) {
                whoRight = i;
                break;
            }
        }
        return whoRight;
    }

    private boolean judgeCanNotPass(DualHeadStorage dualHeadStorage) {
        return dualHeadStorage.getPalletCode() != null ||
                dualHeadStorage.getEnable() == 0;
    }

}
